/*
 * Copyright (c) 2013 Tah Wei Hoon.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License Version 2.0,
 * with full text available at http://www.apache.org/licenses/LICENSE-2.0.html
 *
 * This software is provided "as is". Use at your own risk.
 */

package com.myopicmobile.textwarrior.common;
import com.jamal2362.apktool.util.EditorTheme;



public abstract class ColorScheme
{
	public static class Colorable
	{
		public static Colorable FOREGROUND = new Colorable("FOREGROUND");
		public static Colorable BACKGROUND = new Colorable("BACKGROUND");
		public static Colorable SELECTION_FOREGROUND = new Colorable("SELECTION_FOREGROUND");
		public static Colorable SELECTION_BACKGROUND = new Colorable("SELECTION_BACKGROUND");
		public static Colorable CARET_BACKGROUND = new Colorable("CARET_BACKGROUND");
		public static Colorable CARET_DISABLED = new Colorable("CARET_DISABLED");
		public static Colorable LINE_HIGHLIGHT = new Colorable("LINE_HIGHLIGHT");
		public static Colorable NON_PRINTING_GLYPH = new Colorable("NON_PRINTING_GLYPH");
		public static Colorable COMMENT = new Colorable("COMMENT");
		public static Colorable KEYWORD = new Colorable("KEYWORD");
		public static Colorable NAME = new Colorable("NAME");
		public static Colorable LITERAL = new Colorable("LITERAL");
		public static Colorable OPERATOR = new Colorable("OPERATOR");
		public static Colorable SEPARATOR = new Colorable("SEPARATOR");
		public static Colorable PACKAGE = new Colorable("PACKAGE");
		public static Colorable TYPE = new Colorable("TYPE");
		public static Colorable LINENUMBER_BG = new Colorable("LINENUMBER_BG");
		public static Colorable LINENUMBER_FG = new Colorable("LINENUMBER_FG");
		public static Colorable ERROR = new Colorable("ERROR");

		private Colorable(int light, int dark)
		{
			this.light = light;
			this.dark = dark;
		}

		private Colorable(String n)
		{
			EditorTheme et = new EditorTheme();
			this.light = et.getv(n, 0);
			this.dark = et.getv(n, 1);
		}

		public static void init()
		{
			FOREGROUND = new Colorable("FOREGROUND");
			BACKGROUND = new Colorable("BACKGROUND");
			SELECTION_FOREGROUND = new Colorable("SELECTION_FOREGROUND");
			SELECTION_BACKGROUND = new Colorable("SELECTION_BACKGROUND");
			CARET_BACKGROUND = new Colorable("CARET_BACKGROUND");
			CARET_DISABLED = new Colorable("CARET_DISABLED");
			LINE_HIGHLIGHT = new Colorable("LINE_HIGHLIGHT");
			NON_PRINTING_GLYPH = new Colorable("NON_PRINTING_GLYPH");
			COMMENT = new Colorable("COMMENT");
			KEYWORD = new Colorable("KEYWORD");
			NAME = new Colorable("NAME");
			LITERAL = new Colorable("LITERAL");
			OPERATOR = new Colorable("OPERATOR");
			SEPARATOR = new Colorable("SEPARATOR");
			PACKAGE = new Colorable("PACKAGE");
			TYPE = new Colorable("TYPE");
			LINENUMBER_BG = new Colorable("LINENUMBER_BG");
			LINENUMBER_FG = new Colorable("LINENUMBER_FG");
			ERROR = new Colorable("ERROR");
		}

		final int light, dark;
	}


	public int getColor(Colorable colorable)
	{
		if (isDark())
			return colorable.dark;
		return colorable.light;
	}

	// Currently, color scheme is tightly coupled with semantics of the token types
	public int getTokenColor(int tokenType)
	{
		Colorable element;
		switch (tokenType)
		{
			case Lexer.NORMAL:
				element = Colorable.FOREGROUND;
				break;
			case Lexer.KEYWORD:
				element = Colorable.KEYWORD;
				break;
			case Lexer.NAME:
				element = Colorable.NAME;
				break;
			case Lexer.COMMENT: 
				element = Colorable.COMMENT;
				break;
			case Lexer.SEPARATOR:
				element = Colorable.SEPARATOR;
				break;
			case Lexer.LITERAL:
				element = Colorable.LITERAL;
				break;
			case Lexer.OPERATOR:
				element = Colorable.OPERATOR;
				break;
			case Lexer.UNKNOWN:
				element = Colorable.ERROR;
				break;
			case Lexer.PACKAGE:
				element = Colorable.PACKAGE;
				break;
			default:
				TextWarriorException.fail("Invalid token type");
				element = Colorable.FOREGROUND;
				break;
		}
		return getColor(element);
	}

	/**
	 * Whether this color scheme uses a dark background, like black or dark grey.
	 */
	public abstract boolean isDark();
}
